/*
 * @Author: 谢陈洁
 * @Date: 2025-05-24 13:30:33
 * @LastEditors: 谢陈洁
 * @LastEditTime: 2025-06-26 10:40:01
 * @Description: file content
 */
import { useUserStore } from '@/stores/userStore'
import axios, { type AxiosInstance, type InternalAxiosRequestConfig } from 'axios'

import { ElMessage } from 'element-plus'

// 扩展 AxiosRequestConfig 类型
declare module 'axios' {
  interface AxiosRequestConfig {
    _requestKey?: string
    _retryCount?: number
  }
}

// 存储正在请求的 Promise
const pendingRequests = new Map<string, () => void>()
// 生成唯一请求key、
function generateRequestKey(config: InternalAxiosRequestConfig): string {
  const { method, url, params, data } = config
  return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}

// 创建 Axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_BASE_API,
  withCredentials: true, // 是否携带cookie
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  }
})
// 错误提示统一处理
const showError = (message: string) => {
  ElMessage.error(message)
}
// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const requestKey = generateRequestKey(config)
    if (pendingRequests.has(requestKey)) {
      return Promise.reject(new Error('Duplicate request:'))
    }
    const controller = new AbortController()
    config.signal = controller.signal
    config._requestKey = requestKey

    pendingRequests.set(requestKey, () => controller.abort())

    const token = useUserStore().token || localStorage.getItem('token')
    // console.log('获取用户信息的token:', token)
    // 如果有token，则添加到请求头中
    if (token && config.headers) {
      config.headers.Authorization = `Bearer ${token}`
      config.headers.token = token // 兼容旧版本
    }
    // console.log('请求配置:', config)
    // 如果是POST请求且data存在，则将data转换为JSON字符串
    return config
  },
  (error: any) => {
    return Promise.reject(error)
  }
)
// 响应拦截器
service.interceptors.response.use(
  // (response: AxiosResponse) => {
  response => {
    const requestKey = (response.config as any)._requestKey
    if (requestKey && pendingRequests.has(requestKey)) {
      pendingRequests.delete(requestKey)
    }
    return response
  },
  (error: any) => {
    // 可以统一处理错误
    const config = error?.config as InternalAxiosRequestConfig
    if (config && !axios.isCancel(error)) {
      const requestKey = config._requestKey
      if (requestKey && pendingRequests.has(requestKey)) {
        pendingRequests.delete(requestKey)
      }
    }
    if (!error.response) {
      showError('网络异常，请检查您的网络连接')
      return Promise.reject(error)
    }

    const { status, data } = error.response

    const maxRetry = 3
    if (status === 503) {
      config._retryCount = config._retryCount || 0
      if (config._retryCount < maxRetry) {
        config._retryCount++
        console.log(`Retrying request... Attempt ${config._retryCount}`)
        return new Promise(resolve => setTimeout(resolve, 1000)).then(() => service(config))
      }
    }
    // 处理不同状态码的错误
    const errorMessages: Record<number, string> = {
      401: '未授权，请重新登录',
      403: '权限不足',
      404: '资源不存在',
      500: '服务器内部错误',
      503: '服务暂时不可用'
    }
    const message = data?.message ?? errorMessages[status] ?? '未知错误'
    showError(message)
    if(status === 401) {
      useUserStore().logout()
      // useRouter().push('/login')
    }
    return Promise.reject(error)
  }
)

export default service
